<script setup lang="ts">

defineOptions({name: 'CustomModuleData'})
import { ElMessageBox } from 'element-plus'
import {useTable} from '@/composables/useTable'
import {formatEnumData, dateFormat, arrayGroupBy} from '@/utils/helper'
import {useI18n} from 'vue-i18n'
import {getCustomModuleDataList, deleteCustomModuleData} from '@/api/custom-module-data'
import {getCustomModuleFieldList} from '@/api/custom-module-field'
import {getCustomModuleDataValueList} from '@/api/custom-module-data-value'
import {getEnumData} from '@/api/enum'
import {getLanguageData} from '@/api/language'
import Search from './modules/search.vue'
import Create from './modules/create.vue'
import Update from './modules/update.vue'

/**
 * 变量部分
 */
const {t} = useI18n()
const enumData = ref<any>({})
const enumDataFormat = ref<any>({})
const languageData = ref<any>({})
const route = useRoute()
const params: any = route!.meta!.params
const customModuleId = ref<any>(params?.customModuleId)
const customModuleField = ref<any>([])
const customModuleDataValueGroup = ref<any>({})
const sortField = new Map<string, any>()
const createRef = ref()
const updateRef = ref()

onMounted(async () => {
	await getLanguage()
	await getEnum()
	await getCustomModuleField()
})

const getCustomModuleField = async () => {
	const {list}: any = await getCustomModuleFieldList({
		page: 1, limit: 100,
		customModuleId: customModuleId.value,
		fields: ['labelName', 'fieldName', 'type', 'rule', 'config']
	});
	list.forEach((item: any, key: any) => {
		list[key].rule = JSON.parse(item.rule)
		list[key].config = JSON.parse(item.config)
	})
	customModuleField.value = list
}

/**
 * 表格函数
 */
const {
	columns,
	columnChecks,
	data,
	loading,
	pagination,
	updateColumn,
	searchParams,
	handleSizeChange,
	handleCurrentChange,
	resetSearchParams,
	refreshData,
	getDataDebounced,
} = useTable({
	// 核心配置
	core: {
		apiFn: getCustomModuleDataList,
		apiParams: {
			page: 1,
			limit: 10,
		},
		apiPathParams: customModuleId.value,
		columnsFactory: () => [
			{prop: 'operate', label: t('common.operate'), width: 150, useSlot: true},
			{type: 'expand', label: t('table.column.expand'), width: 85, useSlot: true, slotName: 'expand'},
			{prop: 'status', minWidth: 95, useSlot: true},
			{prop: 'limit', minWidth: 80},
			{prop: 'sort', label: t('common.field.sort'), minWidth: 90, sortable: 'custom'},
			{
				prop: 'createTime', label: t('common.field.createTime'), width: 170, useSlot: true,
				sortable: 'custom',
			},
			{
				prop: 'updateTime', label: t('common.field.updateTime'), width: 170, useSlot: true,
				sortable: 'custom',
			},
		]
	},
	hooks: {
		onSuccess: (data) => {
			if (data.length > 0) handleCustomModuleDataValue()
		},
	}
})

/**
 * 处理自定义模块数据值
 */
const handleCustomModuleDataValue = async () => {
	const customModuleDataIds = data.value.map((item: any) => item.customModuleDataId)
	const params: any = {
		page: 1,
		limit: customModuleDataIds.length * 50,
		customModuleDataIds: customModuleDataIds,
		fields: ['customModuleDataId', 'fieldName', 'fieldValue']
	}
	const {list}: any = await getCustomModuleDataValueList(params)
	const tempGroup: any = arrayGroupBy(list, ['customModuleDataId'])
	const resultGroup: any = {}
	for (let key in tempGroup) {
		const ci: any = tempGroup[key]
		const temp: any = {}
		ci.forEach((item: any) => {
			temp[item.fieldName] = item.fieldValue
		})
		resultGroup[key] = temp
	}
	customModuleDataValueGroup.value = resultGroup
}

/**
 * 获取枚举数据
 */
const getEnum = async () => {
	enumData.value = await getEnumData({modules: ['customModuleData']})
	enumDataFormat.value = formatEnumData(enumData.value)
}

/**
 * 获取语言数据
 */
const getLanguage = async () => {
	const res: any = await getLanguageData({modules: ['customModuleData']});
	languageData.value = {...res};
	for (let key in res.customModuleData.field) updateColumn?.(key, {label: res.customModuleData.field[key]})
}

/**
 * 处理排序改变
 * @param params
 */
const handleSortChange = (params: any) => {
	const hasProp = sortField.has(params.prop);
	if (hasProp && params.order === null) sortField.delete(params.prop)
	else sortField.set(params.prop, params.order)
	let orderBy: any = {};
	for (const [key, value] of sortField) if (value) orderBy[key] = value === 'ascending' ? 'asc' : 'desc'
	// 搜索参数赋值
	Object.assign(searchParams, {orders: {...orderBy}})
	getDataDebounced()
}

/**
 * 处理表头单元格的 className 的回调方法
 * @param column
 */
const handleHeaderCellClassName = ({column}: { column: any }) => {
	if (sortField.has(column.property)) column.order = sortField.get(column.property)
	return ''
}

/**
 * 处理搜索重置
 * @param filterData
 */
const handleSearchReset = (filterData: any) => {
	resetSearchParams()
	Object.assign(searchParams, {...filterData})
	getDataDebounced()
}

/**
 * 处理搜索确认
 * @param filterData
 */
const handleSearchConfirm = (filterData: any) => {
	resetSearchParams()
	Object.assign(searchParams, {...filterData})
	getDataDebounced()
}

/**
 * 处理显示创建
 */
const handleShowCreate = () => createRef.value.open()

/**
 * 处理显示更新
 */
const handleShowUpdate = (id: number | string) => updateRef.value.open(id)


/**
 * 处理删除
 * @param id
 */
const handleDelete = async (id: number | string) => {
	ElMessageBox.confirm(t('common.deleteTip'), t('common.deleteConfirm'), {
		confirmButtonText: t('common.confirm'), cancelButtonText: t('common.cancel'),
		type: 'error', draggable: true
	}).then(() => {
		loading.value = true
		deleteCustomModuleData({customModuleDataId: id}).then(() => refreshData()).finally(() => loading.value = false)
	}).catch(() => {
	})
}
</script>

<!-- art-full-height 自动计算出页面剩余高度 -->
<!-- art-table-card 一个符合系统样式的 class，同时自动撑满剩余高度 -->
<!-- 更多 useTable 使用示例请移步至 功能示例 下面的 高级表格示例 -->
<template>
	<div class="art-full-height">
		<!-- 搜索栏 -->
		<Search :enumData="enumData" :languageData="languageData" @reset="handleSearchReset"
			@search="handleSearchConfirm"/>

		<ElCard class="art-table-card" shadow="never">
			<!-- 表格头部 -->
			<ArtTableHeader v-model:columns="columnChecks" :loading="loading" @refresh="refreshData">
				<template #left>
					<ElSpace wrap>
						<ElButton v-auth="'customModuleDataCreate'" @click="handleShowCreate"
							  v-ripple>
							{{ t('common.create') }}
						</ElButton>
					</ElSpace>
				</template>
			</ArtTableHeader>

			<!-- 表格 -->
			<ArtTable
				:loading="loading"
				:data="data"
				:columns="columns"
				:show-overflow-tooltip="true"
				:default-expand-all="true"
				:header-cell-class-name="handleHeaderCellClassName"
				:pagination="pagination"
				@pagination:size-change="handleSizeChange"
				@pagination:current-change="handleCurrentChange"
				@sort-change="handleSortChange"
			>
				<template #expand="{row}">
					<ElDescriptions
						:column="3"
						:border="false"
					>
						<template v-if="customModuleDataValueGroup[row.customModuleDataId]">
							<ElDescriptionsItem
								v-for="(item, key) in customModuleField"
								:key="key"
								:label="item.labelName">
								{{customModuleDataValueGroup[row.customModuleDataId][item.fieldName]}}
							</ElDescriptionsItem>
						</template>
					</ElDescriptions>
				</template>
				<template #operate="{row}">
					<ArtButtonTable type="edit" v-auth="'customModuleDataUpdate'"
							@click="handleShowUpdate(row.customModuleDataId)"/>
					<ArtButtonTable type="delete" v-auth="'customModuleDataDelete'"
							@click="handleDelete(row.customModuleDataId)"/>
				</template>
				<template #status="{row}">
					<template v-if="enumDataFormat.customModuleData">
						<template v-if="row.status === 1">
							<ElTag type="primary">
								{{ enumDataFormat.customModuleData.status[row.status] }}
							</ElTag>
						</template>
						<template v-if="row.status === 2">
							<ElTag type="danger">
								{{ enumDataFormat.customModuleData.status[row.status] }}
							</ElTag>
						</template>
					</template>
				</template>
				<template #createTime="{row}">{{ dateFormat(row.createTime) }}</template>
				<template #updateTime="{row}">{{ dateFormat(row.updateTime) }}</template>
			</ArtTable>
		</ElCard>
		<Create ref="createRef" :enumData="enumData" :languageData="languageData" @success="refreshData"/>
		<Update ref="updateRef" :enumData="enumData" :languageData="languageData" @success="refreshData"/>
	</div>
</template>

<style lang="scss" scoped>
.art-full-height {
	:deep(.el-descriptions__body) {
		padding-left: 15px;
	}

	:deep(.el-descriptions__label) {
		color: #9797a8;
	}
}
</style>
